module basic_multiplier(LEDR, SW, HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7);
	// Size of multiplier (n*n)
	parameter n = 8;

	// Input and outputs
	input [15:0] SW;
	output [17:0] LEDR;
	output [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7;
	
	// Wires
	wire [7:0] A, B;
	wire [15:0] result;
	wire [7:0] plus, minus, C [7:0], P [7:0], sign, signext[7:0], sign2d [7:0], seC [7:0], seS [7:0];
	
	// Static assignments
	assign A = SW[15:8];
	assign B = SW[7:0];
	
	// Result assignments
	assign result[14:7] = P[7][7:0];
	assign result[15] = sign2d[7][7];
	
	// BCD modules
	BCD(SW[15:12],HEX7);
	BCD(SW[11:8],HEX6);
	BCD(SW[7:4],HEX5);
	BCD(SW[3:0],HEX4);
	
	BCD(result[15:12],HEX3);
	BCD(result[11:8],HEX2);
	BCD(result[7:4],HEX1);
	BCD(result[3:0],HEX0);
	
	assign LEDR[7:0] = C[0][7:0];
	assign LEDR[15:8] = C[1][7:0];
	
	// Multiplier implementation
	genvar i,j;
	
	generate
		for (i = 0; i <= n-1 ; i = i+1) begin:addrow
			if (i == 0)
				booth_encoder(1'b0, A[0], plus[i], minus[i]);
			else begin
				booth_encoder(A[i-1],A[i], plus[i], minus[i]);
				assign result[i-1] = P[i-1][0];
			end

			for (j = 0; j <= n-1 ; j = j+1) begin:addcolumn
				if ((i == 0) & (j == 0))
					basic_multiplier_cell(1'b0, plus[i], minus[i], B[j], minus[i], P[i][j], C[i][j], signext[i][j]);
				else if ((i == 0) & (j != 0))
					basic_multiplier_cell(1'b0, plus[i], minus[i], B[j], C[i][j-1], P[i][j], C[i][j], signext[i][j]);
				else if ((i != 0) & (j == 0))
					basic_multiplier_cell(P[i-1][j+1], plus[i], minus[i], B[j], minus[i], P[i][j], C[i][j], signext[i][j]);
				else if ((i != 0) & (j == n-1))
					basic_multiplier_cell(seS[i-1][i-1], plus[i], minus[i], B[j], C[i][j-1], P[i][j], C[i][j], signext[i][j]);
				else
					basic_multiplier_cell(P[i-1][j+1], plus[i], minus[i], B[j], C[i][j-1], P[i][j], C[i][j], signext[i][j]);
			end
			
			for (j = i; j <= n-1; j = j+1) begin:addse
				if (i==0)
					full_adder(1'b0, signext[i][7], C[i][7], seC[i][j], seS[i][j]);
				else
					full_adder(seS[i-1][j], signext[i][7], C[i][7], seC[i][j], seS[i][j]);
			end

		end
	endgenerate
	
endmodule
 